package com.baomidou.springwind.controller.supply;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.kisso.annotation.Permission;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.springwind.controller.BaseController;
import com.baomidou.springwind.entity.*;
import com.baomidou.springwind.mapper.*;
import com.baomidou.springwind.pojo.SiteCoverBuilder;
import com.baomidou.springwind.pojo.SiteSelection;
import com.baomidou.springwind.pojo.SiteSelectionBuilder;
import com.baomidou.springwind.service.InventoryCostAfterService;
import com.baomidou.springwind.service.OrderDataService;
import com.baomidou.springwind.service.ProjectService;
import com.baomidou.springwind.utils.ParamMap;
import com.baomidou.springwind.utils.ZvalueUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 * 物流供应链-库存持有成本
 * </p>
 *
 * @Author huangtao
 * @Date 2017-8-21
 */
@Controller
@RequestMapping("/network/supply")
public class InventoryCostAfterController extends BaseController {

    @Autowired
    private InventoryCostAfterService inventoryCostAfterService;

    @Autowired
    private InventoryCostAfterDao inventoryCostAfterDao;

    @Autowired
    private NetworkDeliveryDao networkDeliveryDao;
    @Autowired
    private OrderDataDao orderDataDao;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private OrderDataService orderDataService;
    @Autowired
    private SysAreaDao sysAreaDao;
    /**
     * 供应链数据导入
     */
    @RequestMapping("/inventoryAfter/list")
    @Permission("1001")
    public String inventoryList(Model model) {
        EntityWrapper<Project> wrapper = new EntityWrapper<Project>();
        wrapper.eq("operator_id",getCurrentUserId());
        wrapper.in("state", Arrays.asList("1", "2"));
        model.addAttribute("prjList", projectService.selectList(wrapper));
        return pjaxPath("/file/inventory_cost_after_list", model);
    }

    /**
     * 库存持有成本数据--ajax获取数据
     */
    @ResponseBody
    @RequestMapping("/inventoryAfter/getData")
    @Permission("1001")
    public String getData(Page<InventoryCostAfter> page) {
        page = new Page<InventoryCostAfter>(page.getCurrent(), page.getSize());
        EntityWrapper<InventoryCostAfter> wrapper = new EntityWrapper<InventoryCostAfter>();
        String batchId=request.getParameter("batchId");
        if (batchId==null){
            batchId=getProjectId();
        }
        wrapper.eq("batch_id",batchId);
        wrapper.orderBy("create_time", false);
        page = inventoryCostAfterService.selectPage(page, wrapper);
        List<InventoryCostAfter> inventoryCostAfterList = page.getRecords();
        if (inventoryCostAfterList.size() > 0) {
            Project project = projectService.selectById(inventoryCostAfterList.get(0).getBatchId());
            for (InventoryCostAfter inventoryCostAfter : inventoryCostAfterList) {
                inventoryCostAfter.setBatchName(project == null ? "--" : project.getName());
            }
        }
        return jsonPage(page);
    }

    /**
     * 库存持有成本分析界面
     */
    @RequestMapping("/inventoryAfter")
    @Permission("1001")
    public String inventory(Model model) {
        List<SiteSelection> list=getCenterList();
        model.addAttribute("List", list);
        return pjaxPath("/lpp/network/supply/inventoryAfter/main", model);
    }

    @ResponseBody
    @Permission("1001")
    @RequestMapping("/inventoryAfter/bar1")
    public String getbar1(Long batchId, Model model) {
        //根据pm和算法，得到second结果
        ParamMap<String, Object> pm = getParameterMap();
        Map<SiteSelection, List<SiteSelection>> selection=second(pm);
        //算出一级中心siteSelection1，二级中心selectionList
        List<SiteSelection> selectionList=new ArrayList<SiteSelection>();
        SiteSelection siteSelection1=new SiteSelection();
        for (Map.Entry<SiteSelection, List<SiteSelection>> map:selection.entrySet()){
            if (map.getKey().getName().equals(pm.get("center").toString())){
                selectionList=map.getValue();
                siteSelection1=map.getKey();
            }
        }
        //得到2级中心和总需求量
        double simulateDemandSum=0;
        List<Long> stringList=new ArrayList<Long>();
        for(int i=0;i<selectionList.size();i++){
            stringList.add(selectionList.get(i).getLnglatId());
            simulateDemandSum=simulateDemandSum+Double.valueOf(selectionList.get(i).getOrder().toString());
        }
        //得到2级中心所有数据
        EntityWrapper<OrderData> wrapper = new EntityWrapper<OrderData>();
        wrapper.eq("batch_id",getProjectId());
        wrapper.in("delivery_id",stringList);
        List<OrderData> inventoryCostAfterList = orderDataService.selectList(wrapper);
        //根据配车制单日期得到order数据
        Map<String,Object> pm1=new HashMap<String,Object>();
        pm1.put("delivery",stringList);
        pm1.put("batchId",getProjectId());
        List<Map<String, Object>> inventoryCostList2 = orderDataDao.select2(pm1);
        //根据getAll方法，得到ret数据
        JSONObject ret = getAll(siteSelection1,inventoryCostAfterList,inventoryCostList2,pm,simulateDemandSum);
        return callbackSuccess(ret);
    }
    public JSONObject getAll(SiteSelection map,List<OrderData> inventoryCostAfterList,List<Map<String, Object>> inventoryCostList2,ParamMap<String, Object> pms,double simulateDemandSum){
        String prices=pms.get("prize").toString();
        String dealTime=pms.get("dealTime").toString();
        String holdCost=pms.get("holdCost").toString();
        String orderCost=pms.get("orderCost").toString();
        String month=pms.get("months").toString();
        double price=Double.valueOf(prices);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");//创建日期转换对象HH:mm:ss为时分秒，年月日为yyyy-MM-dd
        List<Long> list=new ArrayList<Long>();
        Long advanceTimeSum=0L;
        //处理得到服务水平 提前期 所需要的数据
        for (int i=0;i<inventoryCostAfterList.size();i++){
            int days=node1ToNode2Distance(Double.valueOf(map.getCoordinateY().toString()),Double.valueOf(map.getCoordinateX().toString()),Double.valueOf(inventoryCostAfterList.get(i).getFactoryLat()),Double.valueOf(inventoryCostAfterList.get(i).getFactoryLng()))+Integer.valueOf(dealTime);
            list.add(Long.valueOf(String.valueOf(days)));
            advanceTimeSum=advanceTimeSum+days;
        }
        //服务水平
        String serviceLevelString=pms.get("costomService").toString();
        //计算提前期的标准差
        double advanceAvg=((double)advanceTimeSum)/((double)inventoryCostAfterList.size());
        double advanceStandard=0;
        for (int i=0;i<list.size();i++){
            advanceStandard=advanceStandard+(list.get(i)-advanceAvg)*(list.get(i)-advanceAvg);
        }
        int demandSum=0;
        for (int i=0;i<inventoryCostList2.size();i++){
            demandSum=demandSum+Integer.valueOf(inventoryCostList2.get(i).get("ordersum").toString());
        }
        double demadAvg=demandSum/inventoryCostList2.size();
        //计算的日需求量标准差
        double demadStandard=0;
        for (int i=0;i<inventoryCostList2.size();i++){
            demadStandard=demadStandard+(Integer.valueOf(inventoryCostList2.get(i).get("ordersum").toString())-demadAvg)*(Integer.valueOf(inventoryCostList2.get(i).get("ordersum").toString())-demadAvg);
        }
        double z=ZvalueUtil.getZ(serviceLevelString);
        double value= z*Math.sqrt(demadStandard/inventoryCostList2.size()*advanceAvg+advanceStandard/list.size()*demadAvg*demadAvg);
        //一级配送中心再订货点
        double orderPort=value+demadAvg*advanceAvg;
        // 经济订货批量(EOQ)
        double eoq=Math.sqrt(2*simulateDemandSum*Integer.valueOf(orderCost)/Integer.valueOf(holdCost));
        //订货周期内的周转库存
        double turnoverInventory;
        double dateInterval=0;
        for (int i=1;i<=inventoryCostList2.size();i++){
            try{
                Date preparationCar1=df.parse(inventoryCostList2.get(i-1).get("preparationCar").toString());
                Date preparationCar2=df.parse(inventoryCostList2.get(i).get("preparationCar").toString());
                long diff=preparationCar2.getTime()-preparationCar1.getTime();
                long days=diff/(1000*60*60*24);
                dateInterval=dateInterval+days;
            }catch (Exception e){
            }
        }
        double dateIntervalAvg=dateInterval/inventoryCostList2.size();
        turnoverInventory=demadAvg*(30*eoq*Integer.valueOf(month)/simulateDemandSum);
        //订货周期内的最大库存
        double maxInventory=turnoverInventory+value;
        //订货周期内的平均库存
        double avgInventory=value+turnoverInventory/2;
        //订货周期内库存商品占用资金水平
        double moneyLevel=avgInventory*price;
        //一级配送中心1个月的平均库存
        double months=30;
        double monthAvgInventory=(months/dateIntervalAvg)*avgInventory;
        //到各二级配送中心的总订单量
        double toSecondaryCenter=simulateDemandSum;
        JSONObject ret =new JSONObject();
        ret.put("safetyStock",1+(int)value);
        ret.put("orderPort",1+(int)orderPort);
        ret.put("turnoverInventory",1+(int)turnoverInventory);
        ret.put("maxInventory",1+(int)maxInventory);
        ret.put("eoq",1+(int)eoq);
        ret.put("moneyLevel",1+(int)moneyLevel);
        ret.put("avgInventory",1+(int)avgInventory);
        ret.put("toSecondaryCenter",1+(int)toSecondaryCenter);
        return ret;
    }
    @ResponseBody
    @Permission("1001")
    @RequestMapping("/inventoryAfter/centerList")
    public String centerList() {
        JSONObject ret = new JSONObject();
        List<SiteSelection> siteSelectionList=getCenterList();
        if(siteSelectionList.size()==0){
            String message="没有数据，请上传";
            return callbackFail(message);
        }
        ret.put("centerList",siteSelectionList);
        return callbackSuccess(ret);
    }
    public List<SiteSelection> getCenterList(){
        EntityWrapper<NetworkDelivery> wrapper = new EntityWrapper<NetworkDelivery>();
        wrapper.eq("batch_id", getProjectId());
        List<NetworkDelivery> networkDeliveries = networkDeliveryDao.selectList(wrapper);
        List<NetworkDelivery> firstDeliveryList = new ArrayList<NetworkDelivery>();
        List<NetworkDelivery> secondDeliveryList = new ArrayList<NetworkDelivery>();
        for (NetworkDelivery delivery : networkDeliveries) {
            if (delivery.getType() == 1) {
                firstDeliveryList.add(delivery);
            }if(delivery.getType()==2){
                secondDeliveryList.add(delivery);
            }
        }
        SiteSelectionBuilder builder = new SiteSelectionBuilder(firstDeliveryList, secondDeliveryList);
        List<SiteSelection> siteSelectionList = builder.build();
        return siteSelectionList;
    }
    public String getCenter(){
        List<Map<String, Object>> inventoryCost=inventoryCostAfterDao.selectCenter(getCurrentUserId().toString());
        return inventoryCost.get(0).get("branch_id").toString();
    }
    public Map<SiteSelection, List<SiteSelection>> second(ParamMap<String, Object> pm){
        EntityWrapper<NetworkDelivery> wrapperDelivery = new EntityWrapper<NetworkDelivery>();
        wrapperDelivery.eq("batch_id", getProjectId());
        List<NetworkDelivery> networkDeliveries = networkDeliveryDao.selectList(wrapperDelivery);
        List<NetworkDelivery> firstDeliveryList = new ArrayList<NetworkDelivery>();
        List<NetworkDelivery> secondDeliveryList = new ArrayList<NetworkDelivery>();
        for (NetworkDelivery delivery : networkDeliveries) {
            if (delivery.getType() == 1) {
                firstDeliveryList.add(delivery);
            }if(delivery.getType()==2){
                secondDeliveryList.add(delivery);
            }
        }
        SiteSelectionBuilder builder = new SiteSelectionBuilder(firstDeliveryList, secondDeliveryList);
        List<SiteSelection> siteSelectionList = builder.build();
        SiteCoverBuilder builder1 = new SiteCoverBuilder(siteSelectionList, secondDeliveryList);
        Map<SiteSelection, List<SiteSelection>> map = builder1.build();
        Iterator iter = map.entrySet().iterator();
        Map<SiteSelection, List<SiteSelection>> map1=new HashMap<SiteSelection, List<SiteSelection>>();
        while (iter.hasNext()) {
            Map.Entry entry=(Map.Entry) iter.next();
            SiteSelection siteSelection=(SiteSelection)entry.getKey();
            if (siteSelection.getName().equals(pm.get("center").toString())){
                map1.put((SiteSelection)entry.getKey(),(List<SiteSelection>)entry.getValue());
                break;
            }
        }
        return map1;
    }
    public  int node1ToNode2Distance(double wd1,double jd1,double wd2,double jd2)
    {
        double x,y,out;
        double PI=3.14159265;
        double R=6.371229*1e6;

        x=(jd2-jd1)*PI*R*Math.cos( ((wd1+wd2)/2) *PI/180)/180;
        y=(wd2-wd1)*PI*R/180;
        out=Math.hypot(x,y);
        int time=1+(int)(out/1000)/60/24;
        return time;
    }


}
